package com.fp.admintemplate.common.aspect;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fp.admintemplate.common.annotion.ActionType;
import com.fp.admintemplate.common.annotion.FileInfoAction;
import com.fp.admintemplate.common.files.service.FileInfoService;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.List;

@Component
@Aspect
@RequiredArgsConstructor
public class FilesInfoAspect {

    @Pointcut("@annotation(com.fp.admintemplate.common.annotion.FileInfoAction)")
    public void setFilesFieldPointcut() {
    }

    private final FileInfoService fileInfoService;

    @AfterReturning(value = "setFilesFieldPointcut()", returning = "returnValue")
    public void beforeSetFilesField(JoinPoint joinPoint, Object returnValue) {
        // 获取当前连接点的签名
        String methodName = joinPoint.getSignature().getName();
        // 获取当前类的签名
        String className = joinPoint.getTarget().getClass().getName();


        Class<?> targetClass = joinPoint.getTarget().getClass();
        Method[] declaredMethods = targetClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            if (declaredMethod.getName().equals(methodName)) {
                FileInfoAction annotation = declaredMethod.getAnnotation(FileInfoAction.class);
                ActionType action = annotation.action();
                String typeName = annotation.typeName();
                Object[] args = joinPoint.getArgs();
                switch (action) {
                    case SET -> setFilesField(returnValue, typeName);
                    case SAVE -> saveFilesInfo(args[0], typeName);
                    case UPDATE -> updateFilesInfo(args[0], typeName);
                    case DELETE -> deleteFileInfo(args[0], typeName);
                }
            }
        }

    }

    private void setFilesField(Object obj, String typeName) {
        if (obj instanceof Page<?>) {
            List<?> records = ((Page<?>) obj).getRecords();
            fileInfoService.setFileListBase64(records, typeName);
        } else if (obj instanceof List<?> list) {
            fileInfoService.setFileListBase64(list, typeName);
        } else {
            fileInfoService.setOneFilesBase64(obj, typeName);
        }

    }

    private void updateFilesInfo(Object request, String typeName) {
        Long id = (Long) ReflectUtil.getFieldValue(request, "id");
        List<String> list = (List<String>) ReflectUtil.getFieldValue(request, "files");
        fileInfoService.editOneFIleBase64(id, typeName, CollUtil.getFirst(list));
    }

    private void saveFilesInfo(Object request, String typeName) {
        Long id = (Long) ReflectUtil.getFieldValue(request, "id");
        List<String> list = (List<String>) ReflectUtil.getFieldValue(request, "files");
        fileInfoService.saveFilesInfoBase64(id, typeName, list);
    }

    private void deleteFileInfo(Object request, String typeName) {
        if (request instanceof Long) {
            fileInfoService.deleteFileInfos((Long) request, typeName);
        } else {
            Long id = (Long) ReflectUtil.getFieldValue(request, "id");
            fileInfoService.deleteFileInfos(id, typeName);
        }
    }
}
